import React, { ReactNode, useCallback } from "react";
import * as auth from "auth-provider";
import { http } from "../utils/http";
import { useMount } from "../utils";
import { useAsync } from "../utils/useAsync";
import { FullPageErrorFallback, FullPageLoading } from "../components/lib";
import { bootstrap, selectUser } from "../store/auth.slice";
import { useDispatch, useSelector } from "react-redux";
import * as authStore from "store/auth.slice";
import { useQueryClient } from "react-query";
import { User } from "../types/user";

export interface AuthForm {
  username: string;
  password: string;
}

export const bootstrapUser = async () => {
  let user = null;
  const token = auth.getToken();
  if (token) {
    const data = await http("me", { token });
    user = data.user;
  }
  return user;
};

// const AuthContext = React.createContext<| {
//     user: User | null;
//     register: (form: AuthForm) => Promise<void>;
//     login: (form: AuthForm) => Promise<void>;
//     logout: () => Promise<void>;
// }
//     | undefined>(undefined);
// AuthContext.displayName = "AuthContext";

export const AuthProvider = ({ children }: { children: ReactNode }) => {
  // const [user, setUser] = useState<User | null>(null);
  const { error, isError, isLoading, run, isIdle } = useAsync<User | null>();
  const dispatch: (...args: any[]) => Promise<User> = useDispatch();
  // const login = (form: AuthForm) => auth.login(form).then(setUser);
  // const register = (form: AuthForm) => auth.register(form).then(setUser);
  // const logout = () => auth.logout().then(() => setUser(null));
  useMount(() => {
    // run(bootstrapUser()).then(setUser);
    run(dispatch(bootstrap()));
  });
  if (isIdle || isLoading) {
    return <FullPageLoading />;
  }
  if (isError) {
    return <FullPageErrorFallback error={error} />;
  }
  return <div>{children}</div>;
  // return (
  //     <AuthContext.Provider
  //         children={children}
  //         value={{user, login, register, logout}}
  //     />
  // );
};

export const useAuth = () => {
  // const context = React.useContext(AuthContext);
  // if (!context) {
  //     throw new Error("useAuth必须在AuthContext中使用");
  // }
  //
  // return context

  const dispatch: (...args: any[]) => Promise<User> = useDispatch();
  const user = useSelector(selectUser);
  const queryClient = useQueryClient();
  const login = useCallback(
    (form: AuthForm) => dispatch(authStore.login(form)),
    [dispatch]
  );
  const register = useCallback(
    (form: AuthForm) => dispatch(authStore.register(form)),
    [dispatch]
  );
  const logout = useCallback(() => {
    dispatch(authStore.logout());
    queryClient.clear();
  }, [dispatch, queryClient]);
  return {
    user,
    login,
    logout,
    register,
  };
};
